﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.Security.Permissions;

namespace Fonlow.CommandLineGui.Gui
{
    [PermissionSet(SecurityAction.Demand, Name="FullTrust")]
    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();
        }

       CommandBase command;

       public MainForm(CommandBase command)
            : this()
        {
            Text = "Better Robocopy GUI";
            this.options = command.CommandOptions;
            this.command = command;
            propertyGrid1.SelectedObject = options;
            propertyGrid1.PropertyValueChanged += propertyGrid1_PropertyValueChanged;
            propertyGrid1.SelectedGridItemChanged += new SelectedGridItemChangedEventHandler(propertyGrid1_SelectedGridItemChanged);

            Shown += new EventHandler(MainForm_Shown);
        }

        void propertyGrid1_SelectedGridItemChanged(object sender, SelectedGridItemChangedEventArgs e)
        {
            if (editorEditing)
            {
                editorEditing = false;
                return;
            }

            textBoxHint.Text = e.NewSelection.PropertyDescriptor.Description;
            System.Diagnostics.Debug.WriteLine("selected item changed: " + e.NewSelection.Label);
        }

        TextBoxBase textBox;

        bool editorEditing;

        TextEditorWindow editorWindow;

        void MainForm_Shown(object sender, EventArgs e)
        {
            editorWindow = new TextEditorWindow();
            textBox = editorWindow.TextBox;
            textBox.TextChanged += new EventHandler(textBox_TextChanged);
            editorWindow.Window.Left = Left + Width;
            editorWindow.Window.Top = Top;
            editorWindow.Window.Height = 100;
            editorWindow.Window.Width = Screen.PrimaryScreen.WorkingArea.Width - Width;
            editorWindow.Window.StartPosition = FormStartPosition.Manual;
            editorWindow.WordSelected += new EventHandler<StringEventArgs>(editorWindow_WordSelected);
            editorWindow.Window.FormClosing += new FormClosingEventHandler(Window_FormClosing);
            editorWindow.Window.Show();
        }

        OutputWindow outputWin;

        void Window_FormClosing(object sender, FormClosingEventArgs e)
        {
            Close();
        }

        void OutputWindow_FormClosing(object sender, FormClosingEventArgs e)
        {
            outputWin = null;
        }

        void editorWindow_WordSelected(object sender, StringEventArgs e)
        {
            editorEditing = true;
            textBoxHint.Text =e.Message + ": "+ command.FindParameterHelp(e.Message);
        }

        void textBox_TextChanged(object sender, EventArgs e)
        {
            ReflectFromCommandLineToGrid();
        }

        object options;

        public object CommandOptions { get { return options; } }

        private void propertyGrid1_PropertyValueChanged(object s, PropertyValueChangedEventArgs e)
        {
                ReflectFromGridToCommandLine();
        }

        private void ReflectFromGridToCommandLine()
        {
            textBox.Text = command.CommandLine;
            textBox.SelectionStart = textBox.Text.Length;
        }

        private void ReflectFromCommandLineToGrid()
        {
            command.Load(textBox.Text);
            propertyGrid1.Refresh();
        }

        private void ValidateCommandLine()
        {
            ReflectFromCommandLineToGrid();
            ReflectFromGridToCommandLine();
        }

        private void btnCopy_Click(object sender, EventArgs e)
        {
            ValidateAndCopy();
        }

        private void ValidateAndCopy()
        {
            ValidateCommandLine();
            Clipboard.SetText(textBox.Text);
        }

        private void menuItemAbout_Click(object sender, EventArgs e)
        {
            ShowAbout();
        }

        private void ShowAbout()
        {
            (new AboutForm()).ShowDialog(this);
        }

        private void btnPaste_Click(object sender, EventArgs e)
        {
            textBox.Text = Clipboard.GetText(TextDataFormat.Text);
        }

        private void homeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            GoHome();
        }

        static void GoHome()
        {
            System.Diagnostics.Process.Start("http://www.fonlow.com/BetterRobocopyGUI");
        }

        private void licenseToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ShowLicense();
        }

        static void ShowLicense()
        {
            System.Diagnostics.Process.Start("http://www.fonlow.com/BetterRobocopyGUI/Index.html#License");
        }

        private void btnRun_Click(object sender, EventArgs e)
        {
            RunCommand();
        }

        Process process;

        void RunCommand()
        {
            process = new Process();
            process.StartInfo.FileName = command.CommandName;
            process.StartInfo.Arguments = command.Arguments;
            process.StartInfo.UseShellExecute = false;
            process.StartInfo.CreateNoWindow = true;
            process.StartInfo.RedirectStandardOutput = true;
            process.OutputDataReceived += new DataReceivedEventHandler(process_OutputDataReceived);

            if (outputWin == null)
            {
                outputWin = new OutputWindow();
                outputWin.Window.Left = editorWindow.Window.Left;
                outputWin.Window.Top = editorWindow.Window.Top + editorWindow.Window.Height;
                outputWin.Window.Width = editorWindow.Window.Width;
                outputWin.Window.Height = 300;
                outputWin.Window.StartPosition = FormStartPosition.Manual;
                outputWin.Window.FormClosing += new FormClosingEventHandler(OutputWindow_FormClosing);
                outputWin.Window.Show();
            }
            else
            {
                outputWin.TextBox.Clear();
            }

            process.Start();
            process.BeginOutputReadLine();
        }

        void process_OutputDataReceived(object sender, DataReceivedEventArgs e)
        {
            AddOutputLine(e.Data);
        }

        void AddOutputLine(string s)
        {
            if (s == null)
                s = String.Empty;

            if (outputWin.Window.InvokeRequired)
            {
                Action<string> d = new Action<string>(AddOutputLine);
                Invoke(d, new object[] { s });
            }
            else
            {
                outputWin.TextBox.AppendText(s);
                outputWin.TextBox.AppendText(Environment.NewLine);
            }
        }

    }

}
